package book;

import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

class stu{
    public static  int a = 0;
    public static int b = 0;
}

public class book_thread  {

    Queue<String> queue = new LinkedBlockingQueue<>(10);

    void put(String s) {
        synchronized (queue) {
            // 3
            queue.offer(s);
            queue.notify();
        }
    }

    String take() throws InterruptedException {
        synchronized (queue) {
            while(queue.isEmpty()) {
                // 1
                queue.wait();
                // 2
            }
        }
        return queue.poll();
    }
    // wait notify
    static final Object A = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1= new Thread(new Runnable() {
            public void run() {
                System.out.println("notify 前");
                try {
                    synchronized (A) {
                        A.wait();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("notify 后");
            }
        });

        Thread t2= new Thread(new Runnable() {

            public void run() {
                System.out.println("t2 notify 前");
                try {
                    synchronized (A) {
                        A.wait();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("t2 notify 后");
            }
        });
        t1.start();t2.start();
        Thread.sleep(100);
        synchronized (A) {
            A.notify();
        }

    }


    //线程安全
    // 复课了hhh


    //解决方案
    //死锁
    //约定锁的获取的顺序
    static Object lock1 = new Object();
    static Object lock2 = new Object();
    public static void main14(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                synchronized (lock1) {
                    System.out.println("获取到了locke1");
                    synchronized (lock2) {
                        System.out.println("获取到了lock2");
                    }
                    System.out.println("释放了lock2");
                }
                System.out.println("释放了lock1");
            }
        });

        Thread t2 = new Thread(new Runnable() {
                public void run() {
                    synchronized (lock2) {
                        System.out.println("获取到了locke2");
                        synchronized (lock1) {
                            System.out.println("获取到了lock1");
                        }
                        System.out.println("释放了lock1");
                    }
                    System.out.println("释放了lock2");
                }
        });

        t1.start();
        t2.start();
    }



    // synchronized
    static Object loke = new Object();
    public static void main13(String[] args) throws InterruptedException {
        Thread t1 = new Thread() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    synchronized (loke) {
                        synchronized (loke) {
                            synchronized (loke) {
                                v++;
                            }
                        }
                    }

                }
            }
        };

        Thread t2 = new Thread() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    synchronized (loke) {
                        v++;
                    }
                }
            }
        };

        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println(v);
    }
    //内存可见性
    volatile static int flg = 0;

    public static void main12(String[] args) {
        Thread t1 = new Thread(){
            public void run(){
                while (flg == 0) {

                }
                System.out.println("t1线程退出");
            }
        };

        Thread t2 = new Thread(){
            public void run(){
                System.out.println("读取一个数");
                Scanner sc = new Scanner(System.in);
                flg = sc.nextInt();
                System.out.println("flg = " + flg);
                System.out.println("t2结束");
            }
        };
        t1.start();t2.start();
    }

    static int v = 0;

    public static void main11(String[] args) throws InterruptedException {

        Thread t1 = new Thread() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    v++;
                }
            }
        };

        Thread t2 = new Thread() {
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    v++;
                }
            }
        };
        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println(v);
    }
    //变量捕获，局部变量不允许更改
    public static void main10(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.print("运行中 ");
            }
            System.out.println("线程终止");
        });

        t1.start();
        System.out.println("线程终止");
        t1.interrupt();
    }
    public static void main8(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                while (true) {
                    System.out.print("运行中 ");
                    Thread.sleep(100);
                }
            }catch (InterruptedException e) {
                System.out.println("线程退出");
            }
        });
        t1.start();
        Thread.sleep(100);
        System.out.println("线程终止");
        t1.interrupt();

    }

    //内存可见性
    static int a = 0;
    static Object locker = new Object();

    public static void main7(String[] args) {
        Thread t1 = new Thread(() -> {
            while (true) {
                System.out.print("run");
            }
        });
        t1.setDaemon(true);

        Thread t2 = new Thread(() -> {
            while (true) {
                System.out.print("run");
            }
        });
        t2.setDaemon(true);
        // t1位后台线程 t2为后台线程
        t1.start();t2.start();
    }
    public static void main6(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while(true) {
                synchronized (locker) {
                    a++;
                }
                if (a == -1) {
                    break;
                }
            }
            System.out.println("jiesu");

        });
        Thread t2 = new Thread(() -> {
            while(true){
                synchronized (locker) {
                    a++;
                }
                if(a == -1) {
                    break;
                }
            }
            System.out.println("jiesu");
        });

        //把他设为了后台线程，那么当主线程结束了之后，他也为跟着结束，不管是否运行完
        t1.setDaemon(true);
        t1.start();
        t2.setDaemon(true);
        t2.start();
//        t1.join();
//        t2.join();
        Thread.sleep(10);
        System.out.println(a);
    }
    public static void main5(String[] args) {
        int b = 0;

        stu.a = 1;
        System.out.println("stu a = " +stu.a);
        Thread t1 = new Thread(() -> {
            a += 3;
            if (b == 0) {
                System.out.println(0);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t1 a = " + a);
        });

        Thread t2 = new Thread(() -> {
            System.out.println("t2 gaizhiqina t2 a = " + a);
            a += 5;
            stu.a = 1;
            System.out.println("stu a = " + stu.a);
            System.out.println("t2 a = " + a);
        });
        t1.start();
        t2.start();
    }
    // join
    public static void main4(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.print("1");
            }
            System.out.println();
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.print("2");
            }
            System.out.println();
        });

        //先把1打印完才打印2
        t1.start();t1.join();
        t2.start();t2.join();
        System.out.println("执行完成");
    }
    public static void main3(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 1000; i++) {
                System.out.print(" t1 run ");
            }
        });

        Thread t2 = new Thread(()->{
            for (int i = 0; i < 1000; i++) {
                System.out.print(" t2 run ");
            }
        });

        t1.start();
        t2.start();
        System.out.println("hahah");
        Thread.sleep(1);
        System.out.println("join");
        t1.join();
        t2.join();//这个线程也在执行
        System.out.println("hou");
    }

    // 线程终止
    public static void main2(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            try {
                while (true) {
                    System.out.println("is running");
                    Thread.sleep(100);
                }
            }catch (InterruptedException e) {
                System.out.println("线程终止");
            }
        });

        t1.start();
        System.out.println("interrput前");
        t1.sleep(300);
        t1.interrupt();
        System.out.println("interrupt后");
    }



    public static void main1(String[] args) {
        t1 t1 = new t1();
//        t1.start();
        t1.run();
        //在创建对象是重写方法
        Thread t2 = new Thread(){
            public void run(){
                System.out.println("t2");
            }
        };
//        t2.start();
        t2.run();
        //使用lambda表达式
        Thread t3 = new Thread(()->{
            System.out.println("t3");
        });
//        t3.start();
        t3.run();

        Runnable runnable = new Thread(){
            public void run(){
                System.out.println("t4");
            }
        };
        Thread t4 = new Thread(runnable);

        t4.start();

    }
}

//继承Thread类并重写run方法来创建
class t1 extends Thread{

    @Override
    public void run() {
        System.out.println("hello thread");
    }
}

